<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Util\Err;
use App\Http\Util\HomeTool;
use App\Http\Util\OMUtil;
use App\Http\Util\Tool;
use App\Models\Device;
use App\Models\DeviceCallCountsDaily;
use App\Models\Menus;
use App\Models\Roles;
use App\Models\TestRecord;
use App\Models\User;
use App\Models\UserAddCountHistory;
use App\Models\UserCallCountsDaily;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Response;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Tymon\JWTAuth\Facades\JWTAuth;

class AdminController extends Controller
{


    /**后台登录 with jwt
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $credentials = $request->only('username', 'password');


        if (count($credentials) < 2) {
            return response()->json(['code' => Err::LOGIN_ERROR[0], 'msg' => '账号密码错误']);
        }

        $info = User::where('email', $credentials['username'])
            ->where('is_del', Err::DEL_SHOW)
            ->first();

        if (empty($info)) {
            return response()->json(['code' => Err::LOGIN_ERROR[0], 'msg' => Err::LOGIN_ERROR[1]]);
        }
        if (!Hash::check($credentials['password'], $info->password)) {
            return response()->json(['code' => Err::LOGIN_ERROR[0], 'msg' => Err::LOGIN_ERROR[1]]);
        }
        if (!$token = JWTAuth::fromUser($info)) {
            return response()->json(['code' => Err::LOGIN_ERROR[0], 'msg' => '登录态失效']);
        }
//        Redis::set($token,$token,'EX',60*3);
        return $this->respondWithToken($token);

    }

    /**获取登录态
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        $user = auth('api')->user();
        $info['id'] = $user->id;
        $info['name'] = $user->name;
        $info['email'] = $user->email;
        $info['roles'] = $user->roles;
        $info['avatar'] = $user->avatar;
        $info['roles_id'] = $user->roles_id;
        return response()->json(['code' => Err::SUCCESS[0], 'msg' => Err::SUCCESS[1], 'data' => $info]);
    }

    /**退出登录
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth('api')->logout();

        return response()->json(['code' => Err::SUCCESS[0], 'msg' => Err::SUCCESS[1]]);
    }

    /**
     * Refresh a token.
     * 刷新token，如果开启黑名单，以前的token便会失效。
     * 值得注意的是用上面的getToken再获取一次Token并不算做刷新，两次获得的Token是并行的，即两个都可用。
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(auth('api')->refresh());
    }

    /**返回token
     * Get the token array structure.
     *
     * @param string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'token' => $token,
            'token_type' => 'bearer',
            'code' => 200,
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ]);
    }

    /**获取菜单栏
     * @return \Illuminate\Http\JsonResponse
     */

    public function getMenus()
    {
        $user = auth('api')->user();
        if ($user->roles_id <= 0) {
            $type = 'admin';
            $arr = [];
            $data = Menus::where('pid', 0)
                ->where('is_del', Err::DEL_SHOW)
                ->where('status', Err::DEL_SHOW)
                ->orderBy('sort', 'desc')
                ->get(['id', 'name', 'pid', 'url', 'icon', 'component', 'status', 'label', 'sort'])
                ->toArray();
        } else {
            $type = 'editor';
            $roles = Roles::where('id', $user->roles_id)->value('menus');
            $arr = json_decode($roles, true);
//            ->select(DB::raw('count(*) as user_count, status'))
            $data = Menus::where('pid', 0)
                ->where('is_del', Err::DEL_SHOW)
                ->where('status', Err::DEL_SHOW)
                ->whereIn('id', $arr)
                ->orderBy('sort', 'desc')
                ->get(['id', 'name', 'pid', 'url', 'icon', 'component', 'label', 'sort'])
                ->toArray();
        }
        $data = Tool::getChild($data, $type, $arr);
        return response()->json(['code' => 200, 'msg' => 'ok', 'data' => $data]);
    }


    /**创建编辑菜单
     * @return \Illuminate\Http\JsonResponse
     */
    public function createMenus()
    {
        try {
            $data = request()->post();
            if (!array_key_exists('id', $data) || $data['id'] <= 0) {
                $check_roles = HomeTool::checkRoles(46, 'add');
                if (!$check_roles) {
                    return response()->json(['code' => 1001, 'msg' => '暂无此操作权限']);
                }
                Menus::create($data);
            } else {
                if (array_key_exists('children', $data)) {
                    unset($data['children']);
                }
                $check_roles = HomeTool::checkRoles(46, 'edit');
                if (!$check_roles) {
                    return response()->json(['code' => 1001, 'msg' => '暂无此操作权限']);
                }
                Menus::where('id', $data['id'])->update($data);
            }
            return response()->json(['code' => 200, 'msg' => '操作成功', 'data' => $data]);
        } catch (\Exception $e) {
            return response()->json(['code' => 1001, 'msg' => '操作繁忙 请稍后再试']);
        }

    }

    /**删除菜单
     * @return \Illuminate\Http\JsonResponse
     */
    public function delMenus()
    {
        try {
            $check_roles = HomeTool::checkRoles(46, 'del');
            if (!$check_roles) {
                return response()->json(['code' => 1001, 'msg' => '暂无此操作权限']);
            }
            $id = request()->get('id');
            $child = Menus::where('pid', $id)
                ->where('is_del', Err::DEL_SHOW)
                ->count();
            if ($child > 0) {
                return response()->json(['code' => 1001, 'msg' => '请先删除子菜单']);
            }
            $model = Menus::find($id);
            $model->is_del = Err::DEL_HIDE;
            if ($model->save()) {
                return response()->json(['code' => 200, 'msg' => '删除成功']);
            }
        } catch (\Exception $e) {
            return response()->json(['code' => 1001, 'msg' => '操作繁忙 请稍后再试']);
        }
    }

    /**管理员列表
     * @return \Illuminate\Http\JsonResponse
     */
    public function adminList()
    {
        try {
            $page = request()->only(['page', 'limit', 'keyword', 'type']);
            $list = User::where(function ($query) use ($page) {
                if (array_key_exists('keyword', $page) && $page['keyword']) {
                    $query->where('name', 'like', '%' . $page['keyword'] . '%');
                    $query->orWhere('email', 'like', '%' . $page['keyword'] . '%');
                }
                if (isset($page['type'])) {
                    $query->where('type', $page['type']);
                }
                $query->where('is_del', Err::DEL_SHOW);
            })->orderBy('id', 'desc')
                ->offset(($page['page'] - 1) * $page['limit'])
                ->limit($page['limit'])
                ->get()->toArray();
            foreach ($list as $k => $v) {
                if ($v['roles_id'] > 0) {
                    $list[$k]['roles_name'] = Roles::where('id', $v['roles_id'])->value('name');
                } else {
                    $list[$k]['roles_name'] = '超级管理员';
                }
            }
            $count = User::where(function ($query) use ($page) {
                if (array_key_exists('keyword', $page) && $page['keyword']) {
                    $query->where('name', 'like', '%' . $page['keyword'] . '%');
                    $query->orWhere('email', 'like', '%' . $page['keyword'] . '%');
                }
                if (isset($page['type'])) {
                    $query->where('type', $page['type']);
                }
                $query->where('is_del', Err::DEL_SHOW);
            })->count();
            return response()->json(['data' => $list, 'total' => $count, 'code' => 200]);
        } catch (\Exception $e) {
            return response()->json(['code' => 1001, 'msg' => '操作繁忙 请稍后再试']);
        }
    }

    /**次数调整
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function editCount(Request $request)
    {
        $data = $request->post();
        User::where('id', $data['id'])->update($data);
        return response()->json(['code' => 200, 'msg' => '成功']);
    }

    /**创建管理员
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function create(Request $request)
    {
        $data = $request->post();
        if (!$data['email']) {
            return response()->json(['code' => 1001, 'msg' => '请填写邮箱']);
        }
        if (!$data['name']) {
            return response()->json(['code' => 1002, 'msg' => '请填写姓名']);
        }
        if ($data['roles_id'] > 1) {
            $data['type'] = 2;
        }
        if (array_key_exists('id', $data) && $data['id'] > 0) {
//            $check_roles = HomeTool::checkRoles(17, 'edit');
//            if (!$check_roles) {
//                return response()->json(['code' => 1001, 'msg' => '暂无此操作权限']);
//            }
            $id = $data['id'];
            unset($data['roles_name']);
            if (array_key_exists('updated_at', $data)) {
                unset($data['updated_at']);
            }
            if (array_key_exists('password', $data)) {
                if ($data['password'] == '') {
                    unset($data['password']);
                } else {
                    if (strlen($data['password']) > 30 || strlen($data['password']) < 6) {
                        return response()->json(['code' => 1001, 'msg' => '密码必须为6-30位的字符串']);
                    }
                    $data['password'] = Hash::make($data['password']);
                }
            }
            unset($data['id']);
            User::where('id', $id)->update($data);
        } else {
            $check_roles = HomeTool::checkRoles(17, 'add');
            if (!$check_roles) {
                return response()->json(['code' => 1001, 'msg' => '暂无此操作权限']);
            }
            $check = User::where('email', $data['email'])->where('is_del', Err::DEL_SHOW)->count();
            if ($check > 0) {
                return response()->json(['code' => 1003, 'msg' => '邮箱已被注册']);
            }
            if (strlen($data['password']) > 30 || strlen($data['password']) < 6) {
                return response()->json(['code' => 1001, 'msg' => '密码必须为6-30位的字符串']);
            }
            $data['password'] = Hash::make($data['password']);
            User::create($data);
        }
        return response()->json(['code' => 200, 'msg' => '成功']);
    }

    /**删除管理员
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function del_admin(Request $request)
    {
        $check_roles = HomeTool::checkRoles(17, 'del');
        if (!$check_roles) {
            return response()->json(['code' => 1001, 'msg' => '暂无此操作权限']);
        }
        $id = $request->get('id');
        if (!$id) {
            return response()->json(['code' => 1001, 'msg' => '无此条信息']);
        }
        $model = User::find($id);
        $model->is_del = Err::DEL_HIDE;
        $model->save();
        return response()->json(['code' => 200, 'msg' => '删除成功']);
    }


    /*
        * 导入电表
        */
    public function importDevice(Request $request)
    {
        $file = $request->file('csv_file');
        if ($file->getClientOriginalExtension() !== 'csv') {
            return response()->json(['code' => 1001, 'msg' => '文件格式错误']);
        }
        $username = $request->get('username');
        if (empty($username)) {
            return response()->json(['code' => 1001, 'msg' => '用户名不能为空']);
        }

        //
        //获取文件路径
        $filePath = $file->getPathname();

        $data = OMUtil::getExcelData($filePath);
        OMUtil::trimArray($data[0]);//去掉可能的空格
        foreach ($data as $key => $item) {
            if ($key == 0) {
                $keyArr = array_values($item);
                //判断两个数组的元素是否一样，顺序无所谓
                if (count(array_diff($keyArr, Device::$_csvKeyArr)) > 0) {

                    return response()->json(['code' => 1001, 'msg' => 'csv文件的列名不正确']);
                }
            } else {
                //对数据进行处理
                $needArr[$data[0][0]] = $item[0];
                $needArr[$data[0][1]] = $item[1];
                $needArr[$data[0][2]] = $item[2];
                $needArr[$data[0][3]] = $item[3];
                $needArr[$data[0][4]] = $item[4];
                $userInfo = User::where(function ($query) use ($username) {
                    $query->where('name', $username)   // 用户名匹配
                    ->orWhere('email', $username); // 或账号匹配
                })->first();
                $model = new Device();
                $model->name = $needArr['表号'];
                $model->mac = $needArr['蓝牙Mac地址'];
                $model->module_no = $needArr['主题(IMEI)'];
                $model->iccid = $needArr['物联网卡号'];
                $model->sn = $needArr['二维码编号'];
                $model->user_id = $userInfo->id;
                $model->save();
            }
        }
        return response()->json(['code' => 200, 'msg' => 'ok']);
    }

    /*
     * 电表列表
     */
    public function deviceList(Request $request)
    {
        $pageSize = $request->get('pageSize');
        $pageNum = $request->get('pageNum', 1);
        $name = $request->get('username');
        $field = $request->get('field');
        $startDate = $request->get('startDate');
        $endDate = $request->get('endDate');
        if ($pageNum) {
            $start = $pageSize * ($pageNum - 1);
        } else {
            $start = 0;
        }
        $sort = $request->get('sort');
        if ($sort == '+id') {
            $sort = 'asc';
        } else {
            $sort = 'desc';
        }
        $where = [];
        $userLogin = auth('api')->user();
        $userId = $userLogin->id;
        //如果是管理员，可以查看别人的列表
        if ($userLogin->roles_id == 0) {
            if (!empty($name)) {
                $userModel = User::where(['name' => $name])->first();
                if (!empty($userModel)) {
                    $userId = $userModel->id;
                    $where[] = ['user_id', '=', $userId];
                } else {
                    $where[] = ['user_id', '=', 0];
                }

            }
            //普通用户看自己的
        } else {
            $where[] = ['user_id', '=', $userId];
        }
        //时间范围
        if (!empty($startDate) && !empty($endDate)) {
            $where[] = ['created_at', '>=', $startDate];
            $where[] = ['created_at', '<=', $endDate];
        }


        //or链接多条件可能是name,mac,module_no,iccid,sn

        $list = Device::with('user')->where($where)->where(function ($query) use ($field) {
            if (!empty($field)) {
                $query->where('name', 'like', "%{$field}%")
                    ->orWhere('mac', 'like', "%{$field}%")
                    ->orWhere('module_no', 'like', "%{$field}%")
                    ->orWhere('sn', 'like', "%{$field}%")
                    ->orWhere('iccid', 'like', "%{$field}%");
            }
        })->orderBy('id', $sort)->offset($start)->limit($pageSize)->get();

        $count = Device::where($where)
            ->where(function ($query) use ($field) {
            if (!empty($field)) {
                $query->where('name', 'like', "%{$field}%")
                    ->orWhere('mac', 'like', "%{$field}%")
                    ->orWhere('module_no', 'like', "%{$field}%")
                    ->orWhere('sn', 'like', "%{$field}%")
                    ->orWhere('iccid', 'like', "%{$field}%");
            }
        })->count();

        return response()->json(['code' => 200, 'msg' => 'ok', 'items' => $list, 'total' => $count]);

    }

    /*
     * 禁用电表
     *
     */
    public function deviceDisable(Request $request)
    {
        $id = $request->get('id');
        $state = $request->get('state');
        //state只能是0或1
        if (!in_array($state, array(0, 1))) {
            return response()->json(['code' => 1001, 'msg' => 'state参数错误']);
        }
        $model = Device::find($id);
        //如果结果是空
        if (empty($model)) {
            return response()->json(['code' => 1001, 'msg' => 'id参数错误']);
        }
        $model->is_disabled = $state;
        $model->save();
        return response()->json(['code' => 200, 'msg' => 'ok']);

    }

    /*
 * 删除电表
 * 删除电表的同时，删除电表产测的记录
 *
 */
    public function deviceDel(Request $request)
    {
        $id = $request->get('id');
        $model = Device::find($id);
        //如果结果是空
        if (empty($model)) {
            return response()->json(['code' => 1001, 'msg' => 'id参数错误']);
        }
        $model->delete();
        TestRecord::where('mac', $model->mac)->delete();
        return response()->json(['code' => 200, 'msg' => 'ok']);
    }

    /*
     * 获到用户调用接口的日流水
     */
    public function getUserCallDayFlow(Request $request)


    {
        $pageSize = $request->get('pageSize');
        $pageNum = $request->get('pageNum', 1);
        $userId = $request->get('userId');
        if ($pageNum) {
            $start = $pageSize * ($pageNum - 1);
        } else {
            $start = 0;
        }
        if (!empty($userId)) {
            $where[] = ['user_id', '=', $userId];
        }
        $list = UserCallCountsDaily::where($where)->orderBy('id', 'desc')->offset($start)->limit($pageSize)->get();
        $count = UserCallCountsDaily::where($where)->count();

        return response()->json(['code' => 200, 'msg' => 'ok', 'items' => $list, 'total' => $count]);

    }

    /*
     * 增加调用次数
     */
    public function addCallCount(Request $request)
    {
        $userId = $request->get('userId');
        $count = $request->get('count');
        User::where('id', $userId)->increment('call_count', $count);
        $data = [
            'user_id' => $userId,
            'count' => $count
        ];
        UserAddCountHistory::create($data);
        return response()->json(['code' => 200, 'msg' => 'ok']);
    }

    /*
     * 拉取增加调用次数的流水
     */
    public function getAddCallCountHistory(Request $request)
    {

        $pageSize = $request->get('pageSize');
        $pageNum = $request->get('pageNum', 1);
        $userId = $request->get('userId');
        if ($pageNum) {
            $start = $pageSize * ($pageNum - 1);
        } else {
            $start = 0;
        }
        if (!empty($username)) {
            $where[] = ['user_id', '=', $userId];
        }
        $list = UserAddCountHistory::where($where)->orderBy('id', 'desc')->offset($start)->limit($pageSize)->get();
        $count = UserAddCountHistory::where($where)->count();

        return response()->json(['code' => 200, 'msg' => 'ok', 'items' => $list, 'total' => $count]);

    }


    /*
    * 获到用户调用接口的日流水
    */
    public function getDeviceCallDayFlow(Request $request)
    {
        $pageSize = $request->get('pageSize');
        $pageNum = $request->get('pageNum', 1);
        $mac = $request->get('mac');
        if ($pageNum) {
            $start = $pageSize * ($pageNum - 1);
        } else {
            $start = 0;
        }
        $where = [];
        if (!empty($mac)) {
            $where[] = ['mac', '=', $mac];
        }
        $list = DeviceCallCountsDaily::where($where)->orderBy('id', 'desc')->offset($start)->limit($pageSize)->get();
        $count = DeviceCallCountsDaily::where($where)->count();

        return response()->json(['code' => 200, 'msg' => 'ok', 'items' => $list, 'total' => $count]);

    }

    /*
     * 重置token
     */
    public function resetToken(Request $request)
    {

        $user = auth('api')->user();
        $id = $request->post('id', 0);
        if (!$id) {
            $id = $user->id;
        }
        $model = User::find($id);
        $model->token = md5(__FUNCTION__ . time() . $id);
        $model->save();
        return response()->json(['code' => 200, 'msg' => 'ok', 'token' => $model->token]);
    }

    /*
     * 设置回调的url
     */
    public function setApiUrl(Request $request)
    {
        $user = auth('api')->user();
        $model = User::find($user->id);
        $model->api_url = $request->input('api_url');
        $model->save();
        return response()->json(['code' => 200, 'msg' => 'ok', 'callback_url' => $model->callback_url]);
    }

    /*
     * 获取dashboard页面的一些信息
     */
    public function getDashBoardInfo(Request $request)
    {
        $user = auth('api')->user();
        //如果是管理员
        if ($user->roles_id == 0) {
            //获取设备数量（所有人）
            $where = [['is_disabled', 0]];
            //获取代理商数量
            $agentCount = User::where('roles_id', 2)->count();
            //总次数
            $callCount = User::where('roles_id', 2)->sum('call_count');
            //已使用
            $callCountUsed = User::where('roles_id', 2)->sum('call_count_used');
            //代理商
        } else {
            //获取设备数量
            $where = [['user_id', $user->id], ['is_disabled', 0]];
            $agentCount = 0;
            //总次数
            $callCount = $user->call_count;
            //已使用
            $callCountUsed = $user->call_count_used;
        }

        $deviceCount = Device::where($where)->count();

        //月总调用次数
        $monthCallCount = Device::where($where)->sum('call_count_month');

        //转成int型
        $monthCallCount = intval($monthCallCount);


        return response()->json(['code' => 200, 'msg' => 'ok', 'data' => [
            'agentCount' => $agentCount,
            'callCount' => intval($callCount),
            'callCountUsed' => intval($callCountUsed),
            'deviceCount' => $deviceCount,
            'monthCallCount' => $monthCallCount,
            'roles_id' => $user->roles_id,
            'token'=>$user->token,
            'api_url'=>$user->api_url,
            'id'=>$user->id,
        ]
        ]);
    }


    /**调试
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function sendMsg(Request $request)
    {
        $data = $request->post();
        $user = auth('api')->user();
        if ($user->type > 1) {
            if ($user->call_count <= $user->call_count_used) {
                return response()->json(['code' => 1001, 'msg' => '当前您已无调用次数']);
            }
        }

        $key = 'user_token:' . $user->token;
        if(Redis::exists($key)){
            $data['token'] = $user->token;
        }else{
            $token = md5(uniqid($user->email, true));
            $expireTime = 7200; // 2小时过期
            $key = 'user_token:' . $token;
            $userData = [
                'user_id' => $user->id,
                'account' => $user->email,
                'created_at' => time()
            ];
            // 设置过期时间
            Redis::setex($key, $expireTime, json_encode($userData));
            // 更新用户的 token 字段
            $user->token = $token;
            $user->save();
        }
        $url = 'http://cloud.yimitongxun.com/device/' . $data['path'];
        $result = httpPostRequest($url, $data);
        return response()->json(['code' => 200, 'data' => $result]);
    }


    /*
     * 下载Demo表格
     */
    public function downloadDemo()
    {
        $file = public_path() . '/static/电表导入demo.csv';
        return response()->download($file);
    }

    /*
     * 导出csv列表
     */
    public function exportCsv(Request $request)
    {
        $name = $request->get('username');
        $field = $request->get('field');
        $startDate = $request->get('startDate');
        $endDate = $request->get('endDate');

        $where = [];
        $userLogin = auth('api')->user();
        $userId = $userLogin->id;
        //如果是管理员，可以查看别人的列表
        if ($userLogin->roles_id == 0) {
            if (!empty($name)) {
                $userModel = User::where(['name' => $name])->first();
                if (!empty($userModel)) {
                    $userId = $userModel->id;
                    $where[] = ['user_id', '=', $userId];
                } else {
                    $where[] = ['user_id', '=', 0];
                }

            }
            //普通用户看自己的
        } else {
            $where[] = ['user_id', '=', $userId];
        }
        //时间范围
        if (!empty($startDate) && !empty($endDate)) {
            $where[] = ['created_at', '>=', $startDate];
            $where[] = ['created_at', '<=', $endDate];
            $fileName = '电表列表.' . $startDate . '到' . $endDate . '.csv';

        } else {
            $fileName = '电表列表.csv';

        }

        //or链接多条件可能是name,mac,module_no,iccid,sn

        $list = Device::with('user')->where($where)->where(function ($query) use ($field) {
            if (!empty($field)) {
                $query->where('name', 'like', "%{$field}%")
                    ->orWhere('mac', 'like', "%{$field}%")
                    ->orWhere('module_no', 'like', "%{$field}%")
                    ->orWhere('sn', 'like', "%{$field}%")
                    ->orWhere('iccid', 'like', "%{$field}%");
            }
        })->get(['sn', 'name', 'mac', 'iccid', 'module_no', 'created_at', 'is_master'])->toArray();
        //拼成csv下载
        // 示例数据，你可以替换为从数据库中获取的数据
        $headers = [
            ['二维码编号', '表号', '蓝牙Mac地址', '物联网卡号', '主题(IMEI)', '导入时间', '表类型'],
        ];
        foreach ($list as &$v) {
            if ($v['is_master'] == 1) {
                $v['is_master'] = '4G';
            } else {
                $v['is_master'] = '蓝牙';
            }
        }
        $data = array_merge($headers, $list);

        $csvData = '';
        foreach ($data as $row) {
            $csvData .= implode(',', $row) . "\n";
        }

        return response()->json(['code' => 200, 'data' => $csvData, 'fileName' => $fileName]);


    }

}
